/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

/*
 * SelectEventsPanel.java
 *
 * Created on Aug 28, 2011, 8:37:25 PM
 */
package org.netbeans.modules.debugger.jpda.visual.models;

import java.awt.Color;
import java.awt.Component;
import java.awt.Graphics;
import java.util.Collection;
import java.util.EventObject;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import javax.swing.DefaultListModel;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JCheckBox;
import javax.swing.JList;
import javax.swing.JTable;
import javax.swing.ListCellRenderer;
import javax.swing.event.CellEditorListener;
import javax.swing.event.TableModelListener;
import javax.swing.event.TreeModelListener;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableCellEditor;
import javax.swing.table.TableCellRenderer;
import javax.swing.tree.AbstractLayoutCache;
import javax.swing.tree.TreeModel;
import javax.swing.tree.TreePath;
import org.netbeans.swing.outline.CheckRenderDataProvider;
import org.netbeans.swing.outline.DefaultOutlineModel;
import org.netbeans.swing.outline.Outline;
import org.netbeans.swing.outline.OutlineModel;
import org.netbeans.swing.outline.RowModel;
import org.netbeans.swing.outline.TreePathSupport;

/**
 *
 * @author martin
 */
public class SelectEventsPanel extends javax.swing.JPanel {
    
    private final List<Event> events = new LinkedList<Event>();
    
    /** Creates new form SelectEventsPanel */
    public SelectEventsPanel() {
        initComponents();
    }
    
    public void setData(String[] names, boolean[] logging) {
        int n = names.length;
        for (int i = 0; i < n; i++) {
            Event e = new Event(names[i], logging[i]);
            events.add(e);
        }
        OutlineModel om = DefaultOutlineModel.createOutlineModel(new EventsTreeModel(events), new EventsRowModel(events));
        table.setModel(om);
        ((Outline) table).setRenderDataProvider(new EventsDataProvider(events));
        table.setShowHorizontalLines(false);
        table.setTableHeader(null);
        ((Outline) table).setRootVisible(false);
    }
    
    public boolean[] getLoggingData() {
        int n = events.size();
        boolean[] logging = new boolean[n];
        int i = 0;
        for (Event e : events) {
            logging[i++] = e.isLogging;
        }
        return logging;
    }

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        selectLabel = new javax.swing.JLabel();
        jScrollPane1 = new javax.swing.JScrollPane();
        table = new Outline();

        selectLabel.setText(org.openide.util.NbBundle.getMessage(SelectEventsPanel.class, "SelectEventsPanel.selectLabel.text")); // NOI18N

        jScrollPane1.setViewportView(table);

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
        this.setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 376, Short.MAX_VALUE)
                    .addComponent(selectLabel))
                .addContainerGap())
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(selectLabel)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 267, Short.MAX_VALUE))
        );
    }// </editor-fold>//GEN-END:initComponents
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JLabel selectLabel;
    private javax.swing.JTable table;
    // End of variables declaration//GEN-END:variables

    private static class Event {
        private String clazz;
        private boolean isLogging;

        private Event(String clazz, boolean isLogging) {
            this.clazz = clazz;
            this.isLogging = isLogging;
        }
    }

    private static final class EventsRowModel implements RowModel {

        private final List<Event> events;

        private EventsRowModel(List<Event> events) {
            this.events = events;
        }
        
        @Override
        public int getColumnCount() {
            return 0;
        }

        @Override
        public Object getValueFor(Object node, int column) {
            return null;
        }

        @Override
        public Class getColumnClass(int column) {
            return null;
        }

        @Override
        public boolean isCellEditable(Object node, int column) {
            return false;
        }

        @Override
        public void setValueFor(Object node, int column, Object value) {
            throw new UnsupportedOperationException("Not supported yet.");
        }

        @Override
        public String getColumnName(int column) {
            return "";
        }
        
    }
    
    private static final class EventsTreeModel implements TreeModel {
        
        private List<Event> events;
        
        public EventsTreeModel(List<Event> events) {
            this.events = events;
        }

        @Override
        public Object getRoot() {
            return "ROOT";
        }

        @Override
        public Object getChild(Object parent, int index) {
            return events.get(index);
        }

        @Override
        public int getChildCount(Object parent) {
            if (parent == "ROOT") {
                return events.size();
            } else {
                return 0;
            }
        }

        @Override
        public boolean isLeaf(Object node) {
            return !("ROOT".equals(node));
        }

        @Override
        public void valueForPathChanged(TreePath path, Object newValue) {
            throw new UnsupportedOperationException("Not supported yet.");
        }

        @Override
        public int getIndexOfChild(Object parent, Object child) {
            throw new UnsupportedOperationException("Not supported yet.");
        }

        @Override
        public void addTreeModelListener(TreeModelListener l) {
        }

        @Override
        public void removeTreeModelListener(TreeModelListener l) {
        }
    }
    
    private static final class EventsDataProvider implements CheckRenderDataProvider {
        
        private static final Icon EMPTY_ICON = new EmptyIcon();
        
        private List<Event> events;
        
        public EventsDataProvider(List<Event> events) {
            this.events = events;
        }

        @Override
        public boolean isCheckable(Object o) {
            return true;
        }

        @Override
        public boolean isCheckEnabled(Object o) {
            return true;
        }

        @Override
        public Boolean isSelected(Object o) {
            return ((Event) o).isLogging;
        }

        @Override
        public void setSelected(Object o, Boolean selected) {
            ((Event) o).isLogging = selected;
        }

        @Override
        public String getDisplayName(Object o) {
            return ((Event) o).clazz;
        }

        @Override
        public boolean isHtmlDisplayName(Object o) {
            return false;
        }

        @Override
        public Color getBackground(Object o) {
            return null;
        }

        @Override
        public Color getForeground(Object o) {
            return null;
        }

        @Override
        public String getTooltipText(Object o) {
            return null;
        }

        @Override
        public Icon getIcon(Object o) {
            return EMPTY_ICON;
        }
        
    }
    
    private static final class EmptyIcon implements Icon {

        public EmptyIcon() {
        }
  
        @Override
        public int getIconHeight() {
            return 0;
        }

        @Override
        public int getIconWidth() {
            return 0;
        }

        @Override
        public void paintIcon(Component c, Graphics g, int x, int y) {
        }

    }
}
